CloudFrontの特定UserAgentをチェックするS3の静的ウェブサイトホスティング
AWSチームのすずきです。
静的ウェブサイトホスティング用に設定したAmazon S3、 バケットポリシーでUserAgent判定を行い、特定のCloudFront以外からのアクセスを制限する機会がありましたので、紹介させていただきます。
設定
CloudFront
オリジン設定で、CloudFront標準のUserAgentに任意の文字列を追加する指定を行いました。
- HeadersHeader : User-Agent
- NameValue : Amazon CloudFront <任意文字列>
S3
S3バケットポリシーとして、任意の文字列が付与された CloudFrontのみアクセス(GetObject)を許可する指定を行いました。
{ "Version": "2008-10-17", "Statement": [ { "Effect": "Allow", "Principal": "*", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::<S3バケット>/*", "Condition": { "StringEquals": { "aws:UserAgent": "Amazon CloudFront <任意文字列>" } } } ] }
動作確認
参照可能
- UserAgentに特定文字を設定したCloudFrontは参照可能です。
参照不可
- S3の直接参照は403 Forbiddenとなりました
- UserAgentがデフォルトのCloudFront経由のアクセスは 403 Forbiddenとなりました。
まとめ
S3のウェブサイトホスティングを採用したシンプルなWebサイトだが、 開発中のコンテンツが第三者に参照される事は望ましくないため、CloudFrontへのアクセスは、AWS WAFや、Lambda@Edge などで 実施する場合、 オリジンのS3のアクセス制限する手段として、今回の設定をお試しください。
尚、S3の静的ウェブサイトホスティングをCloudFrontのカスタムオリジンで利用する場合、通信プロトコルはHTTPとなります。 CloudFront、S3間の通信はAWS内で完結する事が期待できますが、全てのグローバルIPを利用した通信で暗号化通信が必要な場合、S3オリジン+OAIでの利用をお勧めします。
CloudFormation
再現用のCloudFormationテンプレートです。
AWSTemplateFormatVersion: '2010-09-09' Description: S3 web hosting with access settings limited to CloudFront Parameters: UseragentToken: Description: Token to add to user agent Type: String Default: hogehoge Resources: S3Bucket: Type: AWS::S3::Bucket Properties: BucketName: !Sub '${AWS::StackName}-${AWS::Region}-${AWS::AccountId}' WebsiteConfiguration: IndexDocument: index.html ErrorDocument: error.html PublicAccessBlockConfiguration: BlockPublicAcls: true BlockPublicPolicy: false IgnorePublicAcls: true RestrictPublicBuckets: false S3BucketPolicy: Type: AWS::S3::BucketPolicy Properties: Bucket: !Ref 'S3Bucket' PolicyDocument: Statement: - Action: s3:GetObject Effect: Allow Resource: - !Sub 'arn:aws:s3:::${S3Bucket}/*' Principal: '*' Condition: StringEquals: aws:UserAgent: !Sub 'Amazon CloudFront ${UseragentToken}' CloudFrontDistribution: Type: AWS::CloudFront::Distribution Properties: DistributionConfig: Origins: - Id: CustumOrigin DomainName: !Sub '${AWS::StackName}-${AWS::Region}-${AWS::AccountId}.s3-website-${AWS::Region}.amazonaws.com' CustomOriginConfig: HTTPPort: 80 OriginProtocolPolicy: http-only OriginCustomHeaders: - HeaderName: User-Agent HeaderValue: !Sub 'Amazon CloudFront ${UseragentToken}' Enabled: 'true' DefaultRootObject: index.html DefaultCacheBehavior: TargetOriginId: CustumOrigin ForwardedValues: QueryString: false ViewerProtocolPolicy: redirect-to-https DefaultTTL: 300 MaxTTL: 300 MinTTL: 300